package com.scalar.chiptrack.adaptor.msilica;

import com.scalar.chiptrack.jobs.JobHandler;
import com.scalar.chiptrack.adaptor.AdaptorConstants;
import com.scalar.chiptrack.adaptor.AdaptorUtils;
import com.scalar.chiptrack.adaptor.AssemblyLot;
import com.scalar.chiptrack.adaptor.InventoryLot;
import com.scalar.chiptrack.adaptor.utils.ParserResult;
import com.scalar.chiptrack.adaptor.utils.Parser;
import com.scalar.chiptrack.adaptor.utils.ParserFactory;
import com.scalar.chiptrack.adaptor.utils.XLSParserImpl;
import com.scalar.chiptrack.adaptor.dao.AdaptorDAO;
import com.scalar.chiptrack.adaptor.dao.AdaptorRunInfo;
import com.scalar.chiptrack.adaptor.dao.InventoryLotDAO;
import com.scalar.chiptrack.adaptor.dao.AssemblyAdaptorDAO;
import com.scalar.chiptrack.utils.Logger;
import com.scalar.chiptrack.utils.StringUtils;
import com.scalar.ScalarException;

import java.util.HashMap;
import java.util.ArrayList;
import java.io.File;

/**
 * Created by IntelliJ IDEA.
 * User: munugoti
 * Date: 19 Jul, 2010
 * Time: 12:47:00 PM
 * To change this template use File | Settings | File Templates.
 */
public class ANSTDataParser extends JobHandler implements AdaptorConstants
{
    private HashMap<String, AssemblyLot> m_assemblyDataMap      = new HashMap<String, AssemblyLot>();
    private HashMap<String, InventoryLot> m_dieBankDataMap      = new HashMap<String, InventoryLot>();

    private Logger m_parserLogger       = null;
    private String m_dataOutputDir      = null;

    public  ANSTDataParser() throws ScalarException
    {
        try
        {
            m_dataOutputDir = AdaptorUtils.getDataOutputDir( VENDOR_NAME_ANST , WIP_TYPE_ASSEMBLY );

            if ( m_dataOutputDir != null )
            {
                AdaptorUtils.makeAllAdaptorDirs( m_dataOutputDir );

                m_parserLogger= AdaptorUtils.getDataParserLogger( m_dataOutputDir,VENDOR_NAME_ANST );

                AdaptorUtils.setLogger( m_parserLogger );
                AssemblyAdaptorDAO.setLogger( m_parserLogger);
                InventoryLotDAO.setLogger( m_parserLogger );
            }
        }
        catch ( Exception se )
        {
            log( "ERROR!! ERROR!! ERROR!! Exception while loading ANST output directory details from database, Exception: " + se );
            System.out.println( "ERROR!! ERROR!! ERROR!! Exception while loading ANST output directory details from database, Exception: " + se );
        }
    }
    public static void main( String args[] ) throws Exception
    {
        try
        {
            new ANSTDataParser().execute();
        }
        catch ( Exception e )
        {
            throw e;
        }
    }
    public void execute() throws Exception
    {
        AdaptorUtils.printHeader( VENDOR_NAME_ANST, CONSTANT_PARSER );

        File doneDestDir = new File( m_dataOutputDir + "/done" );
        File dataoutDir  = new File( m_dataOutputDir );

        File[] fileList = dataoutDir.listFiles();

        if ( ( fileList == null ) || (fileList.length <= 3))
        {
            log("No file found in directory: " + dataoutDir);
            System.out.println("No file found in directory: " + dataoutDir );
            throw new ScalarException("No file found in directory: " + dataoutDir+ "----\n\n" );
        }

        ArrayList<File> successFileList = new ArrayList<File>();

        boolean success;

        for (File aFileList : fileList)
        {
            if (aFileList.isDirectory())
            {
                continue;
            }

            try
            {
                System.out.println("aFileList.getName() = " + aFileList.getName());
                if (aFileList.getName().startsWith(ANSTAdaptor.FILE_NAME_WIP) || aFileList.getName().indexOf(ANSTAdaptor.FILE_NAME_WIP) != -1)
                {
                    parseWipReport(aFileList.getAbsolutePath());

                    successFileList.add(aFileList);
                }

                success = true;
            }
            catch (Exception e)
            {
                success = false;
                log("Exception while parsing file: " + aFileList.getAbsolutePath() + "\nException: " + e);
                e.printStackTrace();
                throw e;
            }
        } //End of for Each
         /*Updating the Die Bank Lot Information*/
        try
        {
            // Save Die Bank Information
            if (m_dieBankDataMap.isEmpty() == false)
            {
                log(" Updating Die Bank Lot Information");
                InventoryLotDAO.saveInventoryLot(null, m_dieBankDataMap.values().iterator(), LOCATION_TYPE_DIE_BANK, VENDOR_NAME_ANST);
            }
            else
            {
                InventoryLotDAO.closeInventoryLot(null, LOCATION_TYPE_DIE_BANK, VENDOR_NAME_ANST);
            }
            success = true;
            m_dieBankDataMap.clear();
            m_dieBankDataMap = null;
        }
        catch (ScalarException se)
        {
            success = false;
            se.printStackTrace();
            log("ERROR!! ERROR!! ERROR!! Could not update Die Bank Lot information into database: " + se);
            throw se;
        }

        try
        {
            // Save Assembly Information
            if ( m_assemblyDataMap.isEmpty() == false )
            {
                log( " Updating Assembly Lot Information" );
                AssemblyAdaptorDAO.saveAssemblyLot( null, m_assemblyDataMap.values().iterator(), WIP_TYPE_ASSEMBLY, VENDOR_NAME_ANST );
            }
            else
            {
                AssemblyAdaptorDAO.closeAssemblyLot( null, WIP_TYPE_ASSEMBLY, VENDOR_NAME_ANST);
            }
            success = true;
            m_assemblyDataMap.clear();
            m_assemblyDataMap = null;
        }
        catch (ScalarException se)
        {
            success = false;
            se.printStackTrace();
            log( "ERROR!! ERROR!! ERROR!! Could not update Assembly Lot information into database: " + se );
            throw se;
        }
        // TO SEND THE NEW LOTS, NEW TRANSIT LOTS, NO PO LOTS, DISCREPANCY LOTS NOTIFICATIONS TO THE USER
        AdaptorDAO.sendAllNotifications( VENDOR_NAME_ANST,true, true, true );

        // To Close the Drop Out Lots
        AdaptorDAO.closeDropOutLots( VENDOR_NAME_ANST );

        int adaptor_id = AdaptorRunInfo.getLastRunAdaptorId( ANSTAdaptor.ADAPTOR_NAME, CONSTANT_ADAPTOR);
        // transaction 9
        try
        {
            if (success)
            {
                AdaptorRunInfo.saveAdaptorLastUpdatedStatus(CONSTANT_PARSER, ANSTAdaptor.ADAPTOR_NAME, CONSTANT_SUCCESS, adaptor_id);
                System.out.println("SUCCESSFULLY UPDATED IN THE DATABASE");
            }
        }
        catch (ScalarException se)
        {
            success = false;  //As filES DATA SAVED , UPDATEING AS SUCCESS
            AdaptorRunInfo.saveAdaptorLastUpdatedStatus(CONSTANT_PARSER, ANSTAdaptor.ADAPTOR_NAME, CONSTANT_SUCCESS, adaptor_id);
            log("WARNING!! WARNING!! WARNING!! Could not update Adaptor run information, Exception: " + se);
            throw se;
        }

        // Step 10
        // Move the successful files to 'done' directory
        if (success)
        {
            AdaptorUtils.moveFilesToDone( successFileList, doneDestDir);
        }
    }

    private void parseWipReport (String fileName ) throws Exception
    {
        if ( fileName == null ) throw new ScalarException( "Filename argument is null" );

        ParserResult result     = null;

        AssemblyLot assemblyLot = null;
        InventoryLot inventoryLot = null;
        String partNumber       = null;
        String fabLotNumber     = null;
        String lotNumber        = null;

        try
        {
            File detailWipFile = new File( fileName );
            if ( !detailWipFile.exists() )
            {
                throw new ScalarException( fileName + " doesnt exist" );
            }

            Parser parser = ParserFactory.getXLSParser( detailWipFile );

            ((XLSParserImpl)parser).setHeaderRowIdx(0);
            ((XLSParserImpl)parser).setDataStartRowIdx(1);

            log( "\nFound " + fileName );
            log( "\nParsing the file for Assembly Wip Report..." );
            System.out.println( "\nFound " + fileName );
            System.out.println( "\nParsing the file for Assembly Wip Report..." );

            result = parser.parse();

            while ( result.next() )
            {
                partNumber      = result.getString("CustomerDevice");
                fabLotNumber    = result.getString("CusOrigwaferlot");
                lotNumber = result.getString("ANST Sub Lot No");
                if ( lotNumber == null )
                {
                    lotNumber = fabLotNumber;
                }

                if ( partNumber != null && partNumber.trim().length() > 0 && fabLotNumber != null && fabLotNumber.trim().length() > 0 )
                {
                    if ( result.getString("Step") != null && result.getString("Step").indexOf("DieBank1") != -1 )
                    {
                        partNumber = partNumber.split("/")[0];
                        //System.out.println("partNumber = " + partNumber);
                        inventoryLot = (InventoryLot)m_dieBankDataMap.get( partNumber + fabLotNumber );

                        if ( inventoryLot == null )
                        {
                            inventoryLot = new InventoryLot( VENDOR_NAME_ANST, LOCATION_TYPE_DIE_BANK );
                            m_dieBankDataMap.put( partNumber + fabLotNumber, inventoryLot );
                        }
                        if (inventoryLot.getQtyIn() != null)
                        {
                            try
                            {
                                inventoryLot.setQtyIn((Integer.parseInt(inventoryLot.getQtyIn()) + result.getInt("Qty")) + "");
                            }
                            catch (Exception e)
                            {
                                inventoryLot.setQtyIn(result.getInt("Qty")+"");
                            }
                        }
                        else
                        {
                            inventoryLot.setQtyIn(result.getInt("Qty") +"");
                        }


                        if (inventoryLot.getQtyIn() != null && !"0".equalsIgnoreCase( inventoryLot.getQtyIn() ) )
                        {
                            inventoryLot.setPartNumber( partNumber );
                            inventoryLot.setLotNumber( fabLotNumber );
                            inventoryLot.setFabLotNumber( fabLotNumber );
                            inventoryLot.setStatus( LOT_STATUS_RUNNING );
                            inventoryLot.setLotCategory( LOT_CATEGORY_TYPE_PROD );
                        }
                    }
                    else
                    {                   
                        log( "In Assembly" + lotNumber ) ;
                        assemblyLot = m_assemblyDataMap.get( partNumber + lotNumber + fabLotNumber );
                        if (assemblyLot == null)
                        {
                            assemblyLot = new AssemblyLot(VENDOR_NAME_ANST );
                            m_assemblyDataMap.put( partNumber + lotNumber + fabLotNumber, assemblyLot);
                        }
                        // FOR SETTING THE QTY IN
                        if( assemblyLot.getQtyIn() != null )
                        {
                            try
                            {
                                assemblyLot.setQtyIn( ( Integer.parseInt( assemblyLot.getQtyIn() )  + result.getInt("Qty")  ) + "" );
                            }
                            catch(Exception e)
                            {
                                assemblyLot.setQtyIn( result.getInt("Qty")+"" );
                            }
                        }
                        else
                        {
                            assemblyLot.setQtyIn( result.getInt("Qty")+"" );
                        }

                        if (assemblyLot.getQtyIn() != null && !"0".equalsIgnoreCase( assemblyLot.getQtyIn() ) )
                        {
                            assemblyLot.setLotNumber( lotNumber );
                            assemblyLot.setDeviceName( partNumber );
                            assemblyLot.setStatus(LOT_STATUS_RUNNING);
                            assemblyLot.setFabLotNumber( fabLotNumber );
                            assemblyLot.setPackageType( result.getString("Package") );
                            assemblyLot.setPONumber( result.getString("CustomerPO"));
                            assemblyLot.setCategory( LOT_CATEGORY_TYPE_PROD );
                            assemblyLot.setStage( result.getString("Step"));
                            if (result.getString("SOD") != null )
                            {
                               assemblyLot.setExpectedDateOut( StringUtils.formatDate(result.getString("SOD"), "yyyy-MM-dd", "MM/dd/yyyy" ) );
                            }
                            assemblyLot.setDateCode( result.getString("Week Mark"));
                            assemblyLot.setProcessType( WIP_TYPE_ASSEMBLY );
                        }
                    }
                }
            }
        }
        catch(Exception e )
        {
            e.printStackTrace();
            throw e;
        }
    }

    private void log( String message )
    {
      if ( message == null ) return;

      if ( m_parserLogger != null )
      {
          m_parserLogger.logDebug( message + LINE_SEPARATOR );
      }
      else
      {
          System.out.println( message );
      }
    } // end of log method

}
